package com.store.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.store.dto.CategoryRequest;
import com.store.entity.Category;
import com.store.entity.Product;
import com.store.mapper.CategoryMapper;
import com.store.mapper.ProductMapper;
import com.store.vo.CategoryVO;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 商品分类服务
 * 
 * @author Store Team
 */
@Service
@RequiredArgsConstructor
public class CategoryService {

    private final CategoryMapper categoryMapper;
    private final ProductMapper productMapper;

    /**
     * 获取所有分类（树形结构）
     */
    public List<CategoryVO> getCategoryTree() {
        // 查询所有分类
        List<Category> allCategories = categoryMapper.selectList(null);
        
        // 转换为VO
        List<CategoryVO> categoryVOList = allCategories.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
        
        // 构建树形结构
        return buildTree(categoryVOList, 0L);
    }

    /**
     * 获取所有分类（列表形式）
     */
    public List<CategoryVO> getCategoryList() {
        LambdaQueryWrapper<Category> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByAsc(Category::getSort);
        wrapper.orderByAsc(Category::getId);
        
        List<Category> categories = categoryMapper.selectList(wrapper);
        return categories.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    /**
     * 根据ID获取分类详情
     */
    public CategoryVO getCategoryById(Long id) {
        Category category = categoryMapper.selectById(id);
        if (category == null) {
            throw new RuntimeException("分类不存在");
        }
        return convertToVO(category);
    }

    /**
     * 创建分类
     */
    @Transactional(rollbackFor = Exception.class)
    public CategoryVO createCategory(CategoryRequest request) {
        // 验证分类名称是否重复
        LambdaQueryWrapper<Category> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Category::getName, request.getName());
        wrapper.eq(Category::getParentId, request.getParentId());
        Long count = categoryMapper.selectCount(wrapper);
        if (count > 0) {
            throw new RuntimeException("同级分类名称已存在");
        }
        
        // 验证父分类是否存在
        if (request.getParentId() != null && request.getParentId() > 0) {
            Category parentCategory = categoryMapper.selectById(request.getParentId());
            if (parentCategory == null) {
                throw new RuntimeException("父分类不存在");
            }
        }
        
        // 创建分类
        Category category = new Category();
        BeanUtils.copyProperties(request, category);
        categoryMapper.insert(category);
        
        return convertToVO(category);
    }

    /**
     * 更新分类
     */
    @Transactional(rollbackFor = Exception.class)
    public CategoryVO updateCategory(CategoryRequest request) {
        // 验证分类是否存在
        Category category = categoryMapper.selectById(request.getId());
        if (category == null) {
            throw new RuntimeException("分类不存在");
        }
        
        // 验证分类名称是否重复
        if (!request.getName().equals(category.getName())) {
            LambdaQueryWrapper<Category> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Category::getName, request.getName());
            wrapper.eq(Category::getParentId, request.getParentId());
            wrapper.ne(Category::getId, request.getId());
            Long count = categoryMapper.selectCount(wrapper);
            if (count > 0) {
                throw new RuntimeException("同级分类名称已存在");
            }
        }
        
        // 验证父分类是否存在
        if (request.getParentId() != null && request.getParentId() > 0) {
            Category parentCategory = categoryMapper.selectById(request.getParentId());
            if (parentCategory == null) {
                throw new RuntimeException("父分类不存在");
            }
            
            // 防止将分类设置为自己的子分类
            if (request.getParentId().equals(request.getId())) {
                throw new RuntimeException("不能将分类设置为自己的子分类");
            }
        }
        
        // 更新分类
        BeanUtils.copyProperties(request, category);
        categoryMapper.updateById(category);
        
        return convertToVO(category);
    }

    /**
     * 删除分类
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteCategory(Long id) {
        Category category = categoryMapper.selectById(id);
        if (category == null) {
            throw new RuntimeException("分类不存在");
        }
        
        // 检查是否有子分类
        LambdaQueryWrapper<Category> categoryWrapper = new LambdaQueryWrapper<>();
        categoryWrapper.eq(Category::getParentId, id);
        Long childCount = categoryMapper.selectCount(categoryWrapper);
        if (childCount > 0) {
            throw new RuntimeException("该分类下存在子分类，不允许删除");
        }
        
        // 检查是否有商品
        LambdaQueryWrapper<Product> productWrapper = new LambdaQueryWrapper<>();
        productWrapper.eq(Product::getCategoryId, id);
        Long productCount = productMapper.selectCount(productWrapper);
        if (productCount > 0) {
            throw new RuntimeException("该分类下存在商品，不允许删除");
        }
        
        categoryMapper.deleteById(id);
    }

    /**
     * 转换为VO对象
     */
    private CategoryVO convertToVO(Category category) {
        CategoryVO vo = new CategoryVO();
        BeanUtils.copyProperties(category, vo);
        
        // 查询商品数量
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Product::getCategoryId, category.getId());
        Long productCount = productMapper.selectCount(wrapper);
        vo.setProductCount(productCount.intValue());
        
        return vo;
    }

    /**
     * 构建树形结构
     */
    private List<CategoryVO> buildTree(List<CategoryVO> categories, Long parentId) {
        List<CategoryVO> tree = new ArrayList<>();
        
        for (CategoryVO category : categories) {
            if (category.getParentId().equals(parentId)) {
                List<CategoryVO> children = buildTree(categories, category.getId());
                category.setChildren(children);
                tree.add(category);
            }
        }
        
        return tree;
    }

}







